package com.app.zhuozhuo

import android.annotation.SuppressLint
import android.app.Application
import android.graphics.Bitmap
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.webkit.*
import kotlinx.coroutines.*
import java.io.File
import java.io.FileInputStream
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.concurrent.*

/**
 *  Create by zhouwd on 2020-01-09
 *  Describe:
 */

private val TAG = "WebViewFactory"

@SuppressLint("StaticFieldLeak")
private var webView: WebView? = null

private val linkedBlockingQueue = LinkedBlockingQueue<String>()

private var job: Job? = null

private const val HANDLER_LOAD_URL = 0x100
private const val HANDLER_BUNDLE_LOAD_URL = "data_url"

private val any = Object()

private var isPreload = false

private val handler = object : Handler(Looper.getMainLooper()) {
    override fun handleMessage(msg: Message) {
        super.handleMessage(msg)
        when(msg.what) {
            HANDLER_LOAD_URL -> {
                val url: String = msg.data.getString(HANDLER_BUNDLE_LOAD_URL, "")
                webView?.settings?.blockNetworkImage = true
                webView?.loadUrl(url)
            }
        }
    }
}

fun block() {
    synchronized(any) {
        any.wait()
    }
}

fun unBlock() {

    synchronized(any) {
        any.notify()
    }

}

interface PreloadResultListener {
    fun onPreloadFinished()
}

private val preloadResultListeners = mutableMapOf<String, PreloadResultListener>()

fun WebViewFactory_addPreloadResultListener(preloadResultListener: PreloadResultListener, url: String) {
    preloadResultListeners[url] = preloadResultListener
}

fun WebViewFactory_removePreloadResultListener(url: String) {
    preloadResultListeners.remove(url)
}

private var mContext: Application? = null

fun WebViewFactory_init(context: Application) {
    mContext = context
    webView = WebView(context)

    webView?.settings?.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK

    // 开启 DOM storage API 功能
    webView?.settings?.domStorageEnabled = false
    //开启 database storage API 功能
    webView?.settings?.databaseEnabled = true

    val cacheDirPath = context.filesDir.absolutePath + "cache/"

    Log.i(TAG, "cacheDirPath ---> $cacheDirPath")

    webView?.settings?.setAppCachePath(cacheDirPath)

    webView?.settings?.setAppCacheEnabled(true)

    webView?.webViewClient = webViewClient
    //开启一个协程
    job = GlobalScope.launch {
        try {
            Log.i(TAG, "job ---> start ---> 1")
            while (true) {
                Log.i(TAG, "job ---> start")
                block()
                Log.i(TAG, "job ---> start ----> 1")
                val url = linkedBlockingQueue.take()
                Log.i(TAG, "job ---> start ----> url ---> $url")
                val bundle = Bundle()
                bundle.putString(HANDLER_BUNDLE_LOAD_URL, url)
                val message = Message()
                message.what = HANDLER_LOAD_URL
                message.data = bundle
                handler.sendMessage(message)

            }
        } finally {

        }

    }

}

fun WebViewFactory_load(url: String, isPreload: Boolean) {

    if (isPreload) {

        Log.i(TAG, "WebViewFactory_load ----> url ---> $url")
        linkedBlockingQueue.put(url)
        Log.i(TAG, "WebViewFactory_load ----> url ---> 111 -->  $url")

    } else {

        webView?.loadUrl(url)

    }
}

fun WebViewFactory_StartPreload() {
    Log.i(TAG, "WebViewFactory_StartPreload")
    isPreload = true
    job?.let {
        Log.i(TAG, "WebViewFactory_StartPreload ----> job")
        unBlock()
        Log.i(TAG, "WebViewFactory_StartPreload ----> job --- 2")

        Log.i(TAG, "WebViewFactory_StartPreload ----> job --- 3")

        Log.i(TAG, "WebViewFactory_StartPreload ----> job --- 1")
    }
}

fun WebViewFactory_StopPreload() {
    Log.i(TAG, "WebViewFactory_StopPreload")
    isPreload = false
    webView?.stopLoading()
    Log.i(TAG, "WebViewFactory_StopPreload ---> 1")
    linkedBlockingQueue.clear()
}

fun WebViewFactory_get():WebView? = webView

private val webViewClient = object : WebViewClient() {

    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        if (isPreload) {
            Log.i(TAG, "webViewClient --> onPageFinished --> url --> $url")
            unBlock()
        }
        val preloadResultListener = preloadResultListeners[url]
        preloadResultListener?.onPreloadFinished()
        Log.i(TAG, "webViewClient --> onPageFinished --> url --> $url")
    }

    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        super.onPageStarted(view, url, favicon)
        Log.i(TAG, "webViewClient --> onPageStarted --> url --> $url")

    }


    override fun shouldInterceptRequest(
        view: WebView?,
        request: WebResourceRequest?
    ): WebResourceResponse? {
        Log.i(TAG, "webViewClient --> shouldInterceptRequest --> url --> ${request?.url}")

        request?.let {

            val url = it.url.toString()

            if (url.contains(".gif") || url.contains(".png") || url.contains(".jpg")) {
                Log.i(TAG, "webViewClient --> shouldInterceptRequest ------------------------> url --> $url")
                val fileName = md5(url)
                mContext?.let {context ->

                    val mime = if (url.contains(".gif")) {
                        "gif"
                    } else if (url.contains(".png")) {
                        "png"
                    } else {
                        "jpg"
                    }

                    val filePath =  "${context.filesDir.absolutePath}image/$fileName.$mime"
                    val file = File(filePath)
                    Log.i(TAG, "webViewClient --> shouldInterceptRequest ----> filePath --> $filePath")
                    if (file.exists()) {
                        Log.i(TAG, "webViewClient --> shouldInterceptRequest ----> filePath --> exit")
                        return WebResourceResponse("image/$mime", "UTF-8" , FileInputStream(file))
                    } else {
                        Log.i(TAG, "webViewClient --> shouldInterceptRequest ----> filePath --> unExit")
                        val worker = NetworkFactory(url, filePath)
                        ImageSaveFactory_addWorker(worker)
                    }
                }
                Log.i(TAG, "webViewClient --> shouldInterceptRequest --> fileName --> $fileName")
            }

        }
        return super.shouldInterceptRequest(view, request)
    }

    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        val url = request?.url

        Log.i(TAG, "webViewClient --> shouldOverrideUrlLoading --> url --> $url")

        if (isPreload) {

        } else {

        }
        return super.shouldOverrideUrlLoading(view, request)
    }

    override fun onLoadResource(view: WebView?, url: String?) {

        super.onLoadResource(view, url)
    }
}

fun md5(text: String): String {
    try {
        //获取md5加密对象
        val instance: MessageDigest = MessageDigest.getInstance("MD5")
        //对字符串加密，返回字节数组
        val digest:ByteArray = instance.digest(text.toByteArray())
        var sb : StringBuffer = StringBuffer()
        for (b in digest) {
            //获取低八位有效值
            var i :Int = b.toInt() and 0xff
            //将整数转化为16进制
            var hexString = Integer.toHexString(i)
            if (hexString.length < 2) {
                //如果是一位的话，补0
                hexString = "0" + hexString
            }
            sb.append(hexString)
        }
        return sb.toString()

    } catch (e: NoSuchAlgorithmException) {
        e.printStackTrace()
    }

    return ""
}

